using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LS.Procedure;
using UnityEngine.Rendering.Universal;
using UnityEngine.U2D;

namespace LS.Scene
{
    public abstract class SceneReference : MonoBehaviour
    {
        public event Action<GameProcedureBase, SceneReference> OnSceneEntry;
        public event Action<GameProcedureBase, SceneReference> OnSceneLeave;
        public event Action<GameProcedureBase, SceneReference> OnScenePrepareStart;
        public event Action<GameProcedureBase, SceneReference> OnScenePrepareFinish;
        
        private bool m_ScenePrepareFinish = false;
        
        [SerializeField]
        private Camera m_Camera;

        [SerializeField]
        private Light m_GlobalLight;
#if URP
        [SerializeField]
        private Light2D m_GlobalLight2D;
#endif

        [SerializeField]
        private AudioListener m_AudioListener;
        
        public bool PrepareFinish => m_ScenePrepareFinish;
        
        public Camera SceneCamera
        {
            get
            {
                return m_Camera;
            }

            set
            {
                m_Camera = value;
            }
        }
        
        public Light GlobalLight
        {
            get
            {
                return m_GlobalLight;
            }
            set
            {
                m_GlobalLight = value;
            }
        }
        
#if URP
        public Light2D GlobalLight2D
        {
            get
            {
                return m_GlobalLight2D;
            }
            set
            {
                m_GlobalLight2D = value;
            }
        }
#endif

        public AudioListener AudioListener
        {
            get
            {
                return m_AudioListener;
            }
            set
            {
                m_AudioListener = value;
            }
        }
        
        protected virtual void Awake()
        {
            if (m_Camera == null)
                m_Camera = GetComponentInChildren<Camera>();
            
            if(m_AudioListener == null)
                m_AudioListener = GetComponentInChildren<AudioListener>();
        }

        protected virtual void Start()
        {
            Debug.Log("SceneReference.Start");
        }

        protected virtual void LateUpdate()
        {
            if (m_Camera != null && m_AudioListener != null)
            {
                m_AudioListener.transform.SetPositionAndRotation(m_Camera.transform.position, m_Camera.transform.rotation);
            }
        }

        internal void OnEntry(GameProcedureBase procedure)
        {
            OnSceneEntry?.Invoke(procedure, this);
            SceneEnterHandler(procedure);
            PrepareScene(procedure);
        }

        internal void OnLeave(GameProcedureBase procedure)
        {
            OnSceneLeave?.Invoke(procedure, this);
            SceneLeaveHandler(procedure);
        }

        internal void PrepareScene(GameProcedureBase procedure)
        {
            procedure?.SceneReferencePrepareStart(this);
            OnScenePrepareStart?.Invoke(procedure, this);
            PrepareSceneStart(procedure);
        }

        protected abstract void PrepareSceneStart(GameProcedureBase procedure);
        
        protected virtual void PrepareSceneFinish(GameProcedureBase procedure)
        {
            OnScenePrepareFinish?.Invoke(procedure, this);
            procedure?.SceneReferencePrepareFinish(this);
            m_ScenePrepareFinish = true;
        }
        
        public virtual void SceneEnterHandler(GameProcedureBase procedure)
        {
            
        }
        
        public virtual void SceneLeaveHandler(GameProcedureBase procedure)
        {
            
        }
    }
}
